package cn.hist.hfp.service;

import cn.hist.hfp.converter.ReservationConverter;
import cn.hist.hfp.converter.UserConverter;
import cn.hist.hfp.entity.Reservation;
import cn.hist.hfp.entity.User;
import cn.hist.hfp.exception.ResourceNotFoundException;
import cn.hist.hfp.repository.ReservationRepository;
import cn.hist.hfp.repository.UserRepository;
import cn.hist.hfp.util.Encryption;
import cn.hist.hfp.vo.ReservationVO;
import cn.hist.hfp.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class UserService {

    private final
    UserRepository userRepository;

    private final
    ReservationRepository reservationRepository;

    private final Encryption encryption;

    private final UserConverter userConverter;

    private final ReservationConverter reservationConverter;

    @Autowired
    public UserService(UserRepository userRepository, Encryption encryption, UserConverter userConverter, ReservationRepository reservationRepository, ReservationConverter reservationConverter) {
        this.userRepository = userRepository;
        this.encryption = encryption;
        this.userConverter = userConverter;
        this.reservationRepository = reservationRepository;
        this.reservationConverter = reservationConverter;
    }

    public User create(User user) {
        user.setPassword(encryption.encodeByMd5(user.getPassword()));
        return userRepository.save(user);
    }

    public User findOne(int id) {
        Optional<User> optionalUser = userRepository.findById(id);
        if (optionalUser.isPresent()) {
            return optionalUser.get();
        }
        throw new ResourceNotFoundException();
    }

    public UserVO findOneVO(int id) {
        return userConverter.convert(findOne(id));
    }

    public UserVO findVOByLoginNameAndPassword(String loginName, String password) {
        return userConverter.convert(findByLoginNameAndPassword(loginName, password));
    }

    public User findByLoginNameAndPassword(String loginName, String password) {
        return userRepository.findByLoginNameAndPassword(loginName, encryption.encodeByMd5(password));
    }

    public User update(User user) {
        return userRepository.save(user);
    }

    public UserVO updateVO(User user) {
        return userConverter.convert(update(user));
    }

    public int delete(int id) {
        Optional<User> optionalUser = userRepository.findById(id);
        optionalUser.ifPresent(userRepository::delete);
        return userRepository.findById(id).isPresent() ? 0 : 1;
    }

    public int checkLoginName(String loginName) {
        return userRepository.findByLoginName(loginName) == null ? 1 : 0;
    }

    public int createReservation(Reservation reservation) {
        reservation.setReservationDate(new Date());
        return reservationRepository.save(reservation) == null ? 0 : 1;
    }

    public List<ReservationVO> findAllReservations(int user_id) {
        Optional<User> optionalUser = userRepository.findById(user_id);
        List<ReservationVO> reservationVOS = new ArrayList<>();
        if (optionalUser.isPresent()) {
            reservationVOS = reservationConverter.convert(reservationRepository.findAllByUser(optionalUser.get()));
        }
        return reservationVOS;
    }

    public int deleteReservation(int id) {
        Optional<Reservation> optionalReservation = reservationRepository.findById(id);
        optionalReservation.ifPresent(reservationRepository::delete);
        return reservationRepository.findById(id).isPresent() ? 0 : 1;
    }
}
